﻿using System;
using System.Net;
using Chat = System.Net;
using System.Threading;
using System.Collections;
using System.IO;
using System.Collections.Generic;

namespace ChatServerApp.Classes
{
    class ServerClass
    {
        System.Net.Sockets.TcpListener chatServer;
        public static Hashtable nickName;
        public static Hashtable nickNameByConnect;
        private List<ClientObject> clientObject;

        public delegate void SendMessageEventHandler(object sender, MessageEventArgs mEA);
        public static event SendMessageEventHandler OnSendMessageHandler;

        public ServerClass()
        {
            CommunicationHandling.OnSendMessageHandler += new CommunicationHandling.SendMessageEventHandler(CommunicationHandling_OnSendMessageHandler);
            nickName = new Hashtable(100);
            nickNameByConnect = new Hashtable(100);
            chatServer = new System.Net.Sockets.TcpListener(IPAddress.Any, Tools.Tools.SERVER_PORT);
            while (true)
            {
                //start the chat server
                chatServer.Start();
                //check if there are any pending connection requests
                if (chatServer.Pending())
                {
                    Chat.Sockets.TcpClient chatConnection = chatServer.AcceptTcpClient();
                    // Console.WriteLine("You are now connected");
                    // OnSendMessage(new MessageEventArgs("You are now connected"));
                    // CommunicationHandling comm = new CommunicationHandling(chatConnection, clientObject);
                    CommunicationHandling comm = new CommunicationHandling(chatConnection);
                }
                Thread.Sleep(500);
            }
        }

        public static void SendMsgToAll(string nick, string msg)
        {
            //create a StreamWriter Object
            StreamWriter writer;
            ArrayList ToRemove = new ArrayList(0);
            //create a new TCPClient Array
            Chat.Sockets.TcpClient[] tcpClient = new Chat.Sockets.TcpClient[ServerClass.nickName.Count];
            //copy the users nickname to the CHatServer values
            ServerClass.nickName.Values.CopyTo(tcpClient, 0);
            //loop through and write any messages to the window
            for (int cnt = 0; cnt < tcpClient.Length; cnt++)
            {
                try
                {
                    //check if the message is empty, of the particular
                    //index of out array is null, if it is then continue
                    if (msg.Trim() == "" || tcpClient[cnt] == null)
                        continue;
                    //Use the GetStream method to get the current memory
                    //stream for this index of our TCPClient array
                    writer = new StreamWriter(tcpClient[cnt].GetStream());
                    //white our message to the window
                    writer.WriteLine(nick + ": " + msg);
                    //make sure all bytes are written
                    writer.Flush();
                    //dispose of the writer object until needed again
                    writer = null;
                }
                    //here we catch an exception that happens
                    //when the user leaves the chatroow
                catch (Exception e44)
                {
                    e44 = e44;
                    string str = (string)ServerClass.nickNameByConnect[tcpClient[cnt]];
                    //send the message that the user has left
                    ServerClass.SendSystemMessage("** " + str + " ** Has Left The Room.");
                    //remove the nickname from the list
                    ServerClass.nickName.Remove(str);
                    //remove that index of the array, thus freeing it up
                    //for another user
                    ServerClass.nickNameByConnect.Remove(tcpClient[cnt]);
                }
            }
        }

        public static void SendSystemMessage(string msg)
        {
            //create our StreamWriter object
            StreamWriter writer;
            ArrayList ToRemove = new ArrayList(0);
            //create our TcpClient array
            Chat.Sockets.TcpClient[] tcpClient = new Chat.Sockets.TcpClient[ServerClass.nickName.Count];
            //copy the nickname value to the chat servers list
            ServerClass.nickName.Values.CopyTo(tcpClient, 0);
            //loop through and write any messages to the window
            for (int i = 0; i < tcpClient.Length; i++)
            {
                try
                {
                    //check if the message is empty, of the particular
                    //index of out array is null, if it is then continue
                    if (msg.Trim() == "" || tcpClient[i] == null)
                        continue;
                    //Use the GetStream method to get the current memory
                    //stream for this index of our TCPClient array
                    writer = new StreamWriter(tcpClient[i].GetStream());
                    //send our message
                    writer.WriteLine(msg);
                    //make sure the buffer is empty
                    writer.Flush();
                    //dispose of our writer
                    writer = null;
                }
                catch (Exception e44)
                {
                    e44 = e44;
                    ServerClass.nickName.Remove(ServerClass.nickNameByConnect[tcpClient[i]]);
                    ServerClass.nickNameByConnect.Remove(tcpClient[i]);
                }
            }
        }

        protected void OnSendMessage(MessageEventArgs e)
        {
            if (OnSendMessageHandler != null)
                OnSendMessageHandler(this, e);
        }

        void CommunicationHandling_OnSendMessageHandler(object sender, MessageEventArgs e)
        {
            this.OnSendMessage(e);
        }
    }

}
